package cn.edu.hhtc.stsystem.security.interceptor;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import cn.edu.hhtc.stsystem.Exception.NoHasRoleException;
import cn.edu.hhtc.stsystem.security.domain.SysUsers;
import cn.edu.hhtc.stsystem.security.service.UserService;
import cn.edu.hhtc.stsystem.security.utils.ThreadLocalRoleId;
import cn.edu.hhtc.stsystem.security.utils.ThreadLocalUserId;
import cn.edu.hhtc.stsystem.service.utils.ServiceUtil;

public class StsUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

	public static final String SPRING_SECURITY_FORM_ROLE_KEY = "j_role";

	private String roleParameter = SPRING_SECURITY_FORM_ROLE_KEY;

	@Autowired
	private UserService userService;

	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
			throws AuthenticationException {

		String role = this.obtainRole(request);
		// 设置登陆页面选择的登陆角色
		ThreadLocalRoleId.setRoleId(NumberUtils.toLong(ServiceUtil.decodeFromDes3(role)));
		Authentication auth = super.attemptAuthentication(request, response);
		if (auth != null) {
			if (StringUtils.isBlank(role)) {
				throw new NoHasRoleException(this.messages.getMessage("LoginAuthentication.noHasRole"));
			} else {
				try {
					SysUsers user = userService.getUserByLoginName(auth.getName());
					if (user != null) {
						try {
							List<Long> roleIdList = this.userService.getRoleIdByUserId(user.getId());
							if (CollectionUtils.isEmpty(roleIdList)
									|| !roleIdList.contains(ThreadLocalRoleId.getRoleId())) {
								throw new NoHasRoleException(this.messages.getMessage("LoginAuthentication.noHasRole"));
							} else {
								ThreadLocalUserId.setUserId(user.getId());
							}
						} catch (Exception e) {
							throw new NoHasRoleException(this.messages.getMessage("LoginAuthentication.noHasRole"));
						}

					} else {
						throw new UsernameNotFoundException(
								this.messages.getMessage("LoginAuthentication.userNotExist"));
					}
				} catch (Exception e) {
					throw new UsernameNotFoundException(this.messages.getMessage("LoginAuthentication.userNotExist"));
				}
			}
		}
		return auth;
	}

	protected String obtainRole(HttpServletRequest request) {
		return request.getParameter(roleParameter);
	}

	public String getRoleParameter() {
		return roleParameter;
	}

	public void setRoleParameter(String roleParameter) {
		this.roleParameter = roleParameter;
	}

}
